package com.marver.common.filter;

import java.io.BufferedReader;  
import java.io.ByteArrayInputStream;  
import java.io.ByteArrayOutputStream;  
import java.io.IOException;  
import java.io.InputStream;  
import java.io.InputStreamReader;  
  

import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;  
import javax.servlet.http.HttpServletRequest;  
import javax.servlet.http.HttpServletRequestWrapper;  
 
/**
 * ServletRequest中getReader()和getInputStream()只能调用一次的解决办法
 * 先将RequestBody保存为一个byte数组，然后通过Servlet自带的HttpServletRequestWrapper
 * 类覆盖getReader()和getInputStream()方法，使流从保存的byte数组读取。
 * 然后再Filter中将ServletRequest替换为ServletRequestWrapper
 * @author kaede
 *
 */
public class MyRequestWrapper extends HttpServletRequestWrapper {  
  
    private final byte[] body;  
      
    public MyRequestWrapper(HttpServletRequest request) throws IOException {  
        super(request);  
        InputStream is = request.getInputStream();  
        ByteArrayOutputStream baos = new ByteArrayOutputStream();  
        byte buff[] = new byte[1024];  
        int read;  
        while( ( read = is.read( buff ) ) > 0 ) {  
            baos.write( buff, 0, read );  
        }  
        body = baos.toByteArray();  
    }  
  
    @Override  
    public BufferedReader getReader() throws IOException {  
        return new BufferedReader(new InputStreamReader(getInputStream()));  
    }  
  
    @Override  
    public ServletInputStream getInputStream() throws IOException {  
        final ByteArrayInputStream bais = new ByteArrayInputStream(body);  
        return new ServletInputStream() {

			@Override
			public boolean isFinished() {
				// TODO Auto-generated method stub
				return false;
			}

			@Override
			public boolean isReady() {
				// TODO Auto-generated method stub
				return false;
			}

			@Override
			public void setReadListener(ReadListener listener) {
				// TODO Auto-generated method stub
				
			}

			@Override
			public int read() throws IOException {
				// TODO Auto-generated method stub
				 return bais.read();
			}  
 
        };  
    }  
  
}  